Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cirq.eject_phased_paulis transformer to replace cirq.EjectPhasedPaulis #4958

Merged
merged 6 commits into from
Feb 8, 2022

Conversation

tanujkhattar
Copy link
Collaborator

@tanujkhattar tanujkhattar commented Feb 7, 2022

Breaking change: cirq.EjectPhasedPaulis optimizer will now remove empty moments by default.

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@CirqBot CirqBot added the size: XL lines changed >1000 label Feb 7, 2022
@MichaelBroughton MichaelBroughton self-assigned this Feb 7, 2022
Copy link
Collaborator

@MichaelBroughton MichaelBroughton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits and then two bigger feedback points:

  1. We should probably have this work with PhasedXZ
  2. Is there a change in behavior on the old transformer that we should fix ?

cirq-core/cirq/optimizers/eject_phased_paulis.py Outdated Show resolved Hide resolved
cirq-core/cirq/transformers/eject_phased_paulis.py Outdated Show resolved Hide resolved
atol: float = 1e-8,
eject_parameterized: bool = False,
) -> 'cirq.Circuit':
"""Transformer pass to push X, Y, and PhasedX gates towards the end of the circuit.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be made to include PhasedXZ gates as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support for PhasedXZ gates with z_exponent = 0 (which are equivalent to PhasedX gates). Added a test which demonstrates how to deal with a general PhasedXZGate, i.e.
run cirq.eject_z(cirq.eject_phased_paulis(cirq.eject_z(c))).

  1. cirq.eject_z(c) : This ejects Z gates and ensures that the z_component of PhasedXZGate is 0.
  2. cirq.eject_phased_paulis(c): This ejects PhasedXPowGates, potentially leaving z phased from CZ phase kickback, which will then be removed by the 3rd cirq.eject_z().

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, could we also support the case where axis_exponent=0 and x_exponent=0 but z_exponent can be whatever we want ? This seems like it might be able to be worked into _try_get_known_z_half_turns without much difficulty ?

@tanujkhattar tanujkhattar added the BREAKING CHANGE For pull requests that are important to mention in release notes. label Feb 7, 2022
@tanujkhattar
Copy link
Collaborator Author

@MichaelBroughton Addressed Feedback, ready for another look.

Copy link
Collaborator

@MichaelBroughton MichaelBroughton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, two concerns now are:

  1. Can we accomodate the PhasedXZ case where axis_exponent=0 and x_xeponent=0 (aka just a Z).
  2. Can we double check that CCO behave themselves when they are the operations that are getting moved (it's good that things work when they aren't getting moved) ?

atol: float = 1e-8,
eject_parameterized: bool = False,
) -> 'cirq.Circuit':
"""Transformer pass to push X, Y, and PhasedX gates towards the end of the circuit.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, could we also support the case where axis_exponent=0 and x_exponent=0 but z_exponent can be whatever we want ? This seems like it might be able to be worked into _try_get_known_z_half_turns without much difficulty ?

atol: float = 1e-8,
eject_parameterized: bool = False,
) -> 'cirq.Circuit':
"""Transformer pass to push X, Y, and PhasedX gates towards the end of the circuit.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to also mention PhasedXZGates in the topline of the docstring.

Comment on lines +334 to +336
[cirq.PhasedXPowGate(phase_exponent=0.25).on(a)],
[cirq.measure(a, key="m")],
[cirq.X(b).with_classical_controls("m")],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the expected output for something like ?

[cirq.PhasedXPowGate(phase_exponent=0.25).on(a)],
[cirq.measure(a, key="m")],
[cirq.X(b).with_classical_controls("m")],
[cirq.measure(b, key='m2')]

?

Copy link
Collaborator Author

@tanujkhattar tanujkhattar Feb 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cirq.X(b).with_classical_controls will be unaffected because op.gate is None for CCOs. The first PhasedXPowGate will get absorbed into the measurement. So, the output will be:

a: ───!M─────────────────
      ║
b: ───╫────X───M('m2')───
      ║    ║
m: ═══@════^═════════════

circuit: 'cirq.AbstractCircuit',
*,
context: Optional['cirq.TransformerContext'] = None,
atol: float = 1e-8,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a little tight, floats are usually only good up to 1e-6 or so.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1e-8 tolerance is standard across the codebase, try running grep -RI '1e-8' --include \*.py.

@tanujkhattar
Copy link
Collaborator Author

  1. Added support for PhasedXZ gates with only z_exponent as the non-zero angle. Also updated docstrings.
  2. CCO's will not get moved because op.gate is None when op is a CCO, so the operation would be an "unknown" operation and will act as a blocker. Same is true for other existing transformers as well. Adding support for running transformers on the gates inside CCOs is currently being discussed in Recursive transformer / iterator  #4923 and I'd prefer to not block this PR for the same.

@tanujkhattar tanujkhattar merged commit c20c99b into quantumlib:master Feb 8, 2022
@tanujkhattar tanujkhattar deleted the eject_phased_pauli branch February 8, 2022 04:20
95-martin-orion pushed a commit to 95-martin-orion/Cirq that referenced this pull request Mar 2, 2022
…edPaulis` (quantumlib#4958)

* Add cirq.eject_phased_paulis transformer to replace cirq.EjectPhasedPaulis

* Add CCO tests, support PhasedXZGates

* Support PhasedXZGates equivalent to z rotations and update docstrings
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
…edPaulis` (quantumlib#4958)

* Add cirq.eject_phased_paulis transformer to replace cirq.EjectPhasedPaulis

* Add CCO tests, support PhasedXZGates

* Support PhasedXZGates equivalent to z rotations and update docstrings
harry-phasecraft pushed a commit to PhaseCraft/Cirq that referenced this pull request Oct 31, 2024
…edPaulis` (quantumlib#4958)

* Add cirq.eject_phased_paulis transformer to replace cirq.EjectPhasedPaulis

* Add CCO tests, support PhasedXZGates

* Support PhasedXZGates equivalent to z rotations and update docstrings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BREAKING CHANGE For pull requests that are important to mention in release notes. size: XL lines changed >1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants